home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
fg
/
fgmisc10
/
menu.c
< prev
next >
Wrap
Text File
|
1993-10-25
|
16KB
|
604 lines
/****************************************************************************\
* *
* menu.c -- menu management functions *
* *
\****************************************************************************/
#include "defs.h"
#include <process.h>
CMD main_menu[] =
{
submenu1, "FILE", 2, 76, 1, 3,
submenu2, "OPTIONS1", 80, 156, 2, 0,
submenu3, "OPTIONS2", 160, 236, 3, 1,
submenu4, "OPTIONS3", 240, 316, 0, 2,
};
CMD menu1[] =
{
load_files, "load ", 2, 76, 1, 5,
null_function, "save", 2, 76, 2, 0,
null_function, "nothing", 2, 76, 3, 1,
null_function, "whatever", 2, 76, 4, 2,
shell, "Shell", 2, 76, 5, 3,
exit_program, "Exit", 2, 76, 0, 4,
};
CMD menu2[] =
{
null_function, "edit", 80, 156, 1, 2,
null_function, "load", 80, 156, 2, 0,
null_function, "save", 80, 156, 0, 1,
};
CMD menu3[] =
{
null_function, "this ",160,236, 1, 3,
null_function, "that", 160,236, 2, 0,
null_function, "the other",160,236, 3, 1,
null_function, "thing", 160,236, 0, 2,
};
CMD menu4[] =
{
null_function, "edit ", 240, 316, 1, 2,
null_function, "load", 240, 316, 2, 0,
null_function, "save", 240, 316, 0, 1,
};
int selection = 0;
FILE *tstream;
/****************************************************************************\
* *
* highlight option -- highlight an option on the main menu *
* *
\****************************************************************************/
void highlight_option(int n)
{
int y;
y = MENU_TOP + 8;
fg_setcolor(black);
fg_rect(main_menu[n].x1,main_menu[n].x2,MENU_TOP,MENU_BOTTOM-1);
fg_setcolor(white);
center_bstring(main_menu[n].menu_item,main_menu[n].x1,main_menu[n].x2,y);
}
/****************************************************************************\
* *
* horizontal_menu -- main menu containing submenus *
* *
\****************************************************************************/
horizontal_menu(CMD cmdtab[],int n,int current)
{
register int i, k;
int c;
int found, new;
int ymin, ymax;
char l;
if (current >= abs(n))
return(ERR);
ymin = MENU_TOP;
ymax = ymin + 10;
fg_mousevis(OFF);
/* set up list of options */
if (n < 0)
{
for (i = 0; i < abs(n); i++)
{
fg_setcolor(white);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(black);
center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
}
fg_save(0,319,MENU_TOP,MENU_BOTTOM);
}
/* highlight current option */
i = current;
fg_setcolor(black);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(white);
center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
/* if we're just displaying the menu options, return */
if (n < 0) return(OK);
fg_mousevis(ON);
/* choose an option */
new = current;
fg_setnum(OFF);
flushkey();
for(;;)
{
/* activate the corresponding vertical menu */
main_option = i;
c = (*cmdtab[i].menu_func)();
/* cycle through choices */
if (c == LEFT_ARROW || c == BS)
new = cmdtab[i].prev;
else if (c == RIGHT_ARROW || c == SPACEBAR)
new = cmdtab[i].next;
else if (c >= 0 && c <= n)
new = c;
else if (c == ESC)
{
exit_program();
return(i);
}
else if (isalpha(c))
{
c = tolower(c);
found = FALSE;
for (k = i+1; k < n; k++)
{
l = first_nonblank(cmdtab[k].menu_item);
if (c == tolower((int)l))
{
found = TRUE;
break;
}
}
if (!found)
{
for (k = 0; k <= i; k++)
{
l = first_nonblank(cmdtab[k].menu_item);
if (c == (char)tolower((int)l))
{
found = TRUE;
break;
}
}
}
if (found)
new = k;
else
{
main_option = i;
return(i);
}
}
else
{
main_option = i;
return(i);
}
if (i != new)
{
/* unmark previous option */
fg_mousevis(OFF);
fg_setcolor(white);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(black);
center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
/* mark new option */
i = new;
fg_setcolor(black);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(white);
center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
fg_mousevis(ON);
}
}
}
/****************************************************************************\
* *
* submenus *
* *
\****************************************************************************/
submenu1()
{
return(vertical_menu(menu1,0,6));
}
submenu2()
{
return(vertical_menu(menu2,1,3));
}
submenu3()
{
return(vertical_menu(menu3,2,4));
}
submenu4()
{
return(vertical_menu(menu4,3,3));
}
/****************************************************************************\
* *
* vertical_menu -- submenu off main menu *
* *
\****************************************************************************/
vertical_menu(CMD cmdtab[],int index,int n)
{
register int i, j, k;
int found, new;
int height;
int left, right;
int string_x;
int x1, x2, y1, y2;
int ymin, ymax;
int count;
char c, l;
unsigned char key, aux;
/* height in pixels of an individual menu item */
height = 10;
/* the first menu item determines the x coordinate for the other items */
string_x = get_center(cmdtab[0].menu_item,cmdtab[0].x1,cmdtab[0].x2);
/* define the menu extremes */
x1 = cmdtab[0].x1 - 1;
x2 = cmdtab[0].x2 + 3;
y1 = MENU_BOTTOM+1;
y2 = MENU_BOTTOM + n*height + 1;
/* define the associated horizontal mouse limits */
if (mouse)
{
left = mouse_limits[index];
right = mouse_limits[index+1] - 2;
}
/* display the vertical menu if necessary */
if (redraw)
{
/* do this stuff on the hidden page to make it look faster */
fg_setpage(HIDDEN);
/* draw the menu outline and the shadow around it */
fg_mousevis(OFF);
fg_setcolor(white);
fg_box(x1,x2-2,y1,y2-1);
fg_setcolor(dkblue);
fg_rect(x1+1,x2,y2+1,y2+1);
fg_rect(x1+2,x2,y2+2,y2+2);
fg_rect(x2-1,x2,y1,y2+2);
fg_setcolor(black);
fg_box(x1,x2-2,y1,y2);
/* set up list of options */
ymax = MENU_BOTTOM;
for (i = 0; i < n; i++)
{
ymin = ymax + 1;
ymax = ymin + height-1;
fg_setcolor(white);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(black);
put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
}
/* highlight first or previously selected option */
i = selection;
ymin = MENU_BOTTOM + i*height;
ymax = ymin + height;
fg_setcolor(black);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(white);
put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
/* restore the menu to the visual page */
fg_setpage(VISUAL);
fg_restore(x1,x2,y1,y2+2);
redraw = FALSE;
fg_setpage(HIDDEN);
/* clear the hidden page under the menu */
fg_setcolor(blue);
fg_rect(x1,x2,y1,y2+2);
fg_setpage(VISUAL);
fg_mousevis(ON);
}
/* choose an option */
i = selection;
new = i;
fg_setnum(OFF);
flushkey();
for(;;)
{
/* read a keystroke */
fg_mousevis(ON);
fg_waitfor(1);
fg_intkey(&key,&aux);
/* if using a mouse, check its position */
if (mouse && key+aux == 0)
{
fg_mousebut(1,&count,&xmouse,&ymouse);
if (count > 0)
{
if (BETWEEN(xmouse,x1,x2) && BETWEEN(ymouse,y1,y2-2))
{
new = (ymouse - y1) / height;
/* check if this is the second click of a double click */
if (i == new)
key = CR;
}
else if (!BETWEEN(xmouse,left,right) && BETWEEN(ymouse,MENU_TOP,y1-1))
{
fg_mousevis(OFF);
fg_restore(0,xlimit,MENU_BOTTOM,ylimit);
redraw = TRUE;
selection = 0;
for (j = 0; j <= ITEMS; j++)
{
if (BETWEEN(xmouse,mouse_limits[j],mouse_limits[j+1]))
return(j);
}
}
else
{
fg_mousevis(OFF);
fg_restore(0,xlimit,MENU_BOTTOM,ylimit);
redraw = TRUE;
selection = 0;
return(-1);
}
}
}
/* cycle through choices */
if (aux == UP_ARROW || key == BS)
new = cmdtab[i].prev;
else if (aux == DOWN_ARROW || key == SPACEBAR)
new = cmdtab[i].next;
else if (aux == HOME || aux == PGUP)
new = 0;
else if (aux == END || aux == PGDN)
new = n - 1;
else if (aux == LEFT_ARROW || aux == RIGHT_ARROW)
{
fg_mousevis(OFF);
fg_restore(0,xlimit,MENU_BOTTOM,ylimit);
redraw = TRUE;
selection = 0;
return((int)aux);
}
/* pick one choice */
else if (key == CR)
{
(*cmdtab[i].menu_func)();
wait_for_mouse_buttons();
selection = i;
return(index);
}
else if (key == ESC)
{
selection = 0;
return(ESC);
}
else if (isalpha((int)key))
{
c = (char)tolower((int)key);
found = FALSE;
for (k = i+1; k < n; k++)
{
l = first_nonblank(cmdtab[k].menu_item);
if (c == (char)tolower((int)l))
{
found = TRUE;
break;
}
}
if (!found)
{
for (k = 0; k <= i; k++)
{
l = first_nonblank(cmdtab[k].menu_item);
if (c == (char)tolower((int)l))
{
found = TRUE;
break;
}
}
}
if (found)
new = k;
else
{
redraw = TRUE;
return(-1);
}
}
else if (key+aux > 0) /* any other key */
{
redraw = TRUE;
return(-1);
}
if (i != new)
{
/* unmark previous option */
ymin = MENU_BOTTOM + i*height;
ymax = ymin + height;
fg_mousevis(OFF);
fg_setcolor(white);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(black);
put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
/* mark new option */
i = new;
ymin = MENU_BOTTOM + i*height;
ymax = ymin + height;
fg_setcolor(black);
fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
fg_setcolor(white);
put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
/* move mouse cursor to the new option */
if (mouse)
{
fg_mousepos(&xmouse,&ymouse,&buttons);
if (BETWEEN(xmouse,x1,x2)) fg_mousemov(xmouse,(ymin+ymax)/2);
fg_mousevis(ON);
}
}
}
}
null_function()
{
return(OK);
}
/****************************************************************************\
* *
* exit_program -- from menu *
* *
\****************************************************************************/
exit_program()
{
quit_graphics();
return(0);
}
/****************************************************************************\
* *
* first_nonblank -- find first character that is not a blank *
* *
\****************************************************************************/
char first_nonblank(char *string)
{
register int i;
char c;
i = 0;
for(;;)
{
c = string[i++];
if (c == 0)
return(0);
else if (c > 32)
return(c);
}
}
/****************************************************************************\
* *
* shell -- create a DOS command shell *
* *
\****************************************************************************/
shell()
{
int count;
fg_mousepos(&xmouse,&ymouse,&buttons);
fg_mousevis(0);
fg_setmode(3);
fg_mouseini();
fg_reset();
/* spawn the DOS command shell */
printf("\nType 'Exit' to return to the menu.\n");
spawnlp(P_WAIT,"command.com",NULL);
/* upon return from DOS, restore the video context */
fg_setmode(22);
fg_setpage(0);
fg_setvpage(0);
fg_sethpage(1);
init_mouse();
fg_mousevis(0);
/* redraw the screen */
draw_screen();
redraw = TRUE;
fg_mousemov(xmouse,ymouse);
fg_mousebut(1,&count,&xmouse,&ymouse);
fg_mousebut(2,&count,&xmouse,&ymouse);
return(OK);
}
/****************************************************************************\
* *
* wait_for_mouse_buttons -- wait until no mouse buttons are pressed *
* *
\****************************************************************************/
void wait_for_mouse_buttons()
{
int buttons;
int x, y;
if (mouse)
{
do
fg_mousepos(&x,&y,&buttons);
while (buttons&3);
}
}